package com.moonshineproject.plugin.settings.vo
{   
    import flash.events.EventDispatcher;
    
    import mx.core.IVisualElement;

    public class AbstractSetting extends EventDispatcher implements ISetting
    {
		private var hasPendingChanges:Boolean = false;
		private var pendingChanges:*
    	
        private var _name:String;
        [Bindable]
        public function get name():String
        {
            return _name;
        }
        public function set name(v:String):void
        {
            _name = v;
        }

        private var _label:String;
        [Bindable]
        public function get label():String
        {
            return _label;
        }
        public function set label(v:String):void
        {
            _label = v;
        }

        public function get renderer():IVisualElement
        {
            return null;
        }

        protected var _provider:Object
        public function get provider():Object
        {
            return _provider;
        }
        public function set provider(v:Object):void
        {
            _provider = v;
        }

        private var _defaultValue:String;
        protected function get defaultValue():String
        {
            return _defaultValue;
        }
        protected function set defaultValue(v:String):void
        {
            _defaultValue = v;
			
        }

        // Used to save to disc — if you want to serialize do so here.
        [Bindable]
        public function get stringValue():String
        {
			//if(pendingChanges) return pendingChanges.toString();
            return getSetting().toString();
        }
        public function set stringValue(v:String):void
        {
            setPendingSetting(v);
        }

        // Fetches default values from the provider
        protected function getSetting():*
        {
            if (!hasProperty())
                return "";
			if(pendingChanges != null)return  pendingChanges;
            return provider[name] != null ? provider[name] : "";
        }

        protected function hasProperty(... names:Array):Boolean
        {
            names = names || [name];

            if (!provider)
                return false;
            for each (var n:String in names)
            {
                if (!Object(provider).hasOwnProperty(n))
                    return false;
            }
            return true;

        }
		

        // Commits changes back to provider
        protected function setPendingSetting(v:*):void
        {
        	hasPendingChanges = true;
			pendingChanges = v;           
        }

        public function valueChanged():Boolean
        {
            return (hasPendingChanges && defaultValue !== pendingChanges);
        }
		
		public function commitChanges():void
		{
			if (!hasProperty() || !hasPendingChanges) return;
				
			provider[name] = pendingChanges;
			hasPendingChanges = false;
		}

    }
}